using System;
using Xunit;
using Xunit.Abstractions;

namespace muduoDotNet.Tests.Common
{
    /// <summary>
    /// 测试基类，提供公共的测试设置和工具方法
    /// </summary>
    public abstract class TestBase : IDisposable
    {
        protected readonly ITestOutputHelper Output;
        private bool _disposed = false;

        protected TestBase(ITestOutputHelper output)
        {
            Output = output ?? throw new ArgumentNullException(nameof(output));
            Setup();
        }

        /// <summary>
        /// 测试初始化
        /// </summary>
        protected virtual void Setup()
        {
            // 默认为空，子类可以重写
        }

        /// <summary>
        /// 测试清理
        /// </summary>
        protected virtual void Cleanup()
        {
            // 默认为空，子类可以重写
        }

        /// <summary>
        /// 记录测试输出
        /// </summary>
        /// <param name="message">消息</param>
        protected void LogInfo(string message)
        {
            Output.WriteLine($"[INFO] {DateTime.Now:HH:mm:ss.fff} {message}");
        }

        /// <summary>
        /// 记录警告
        /// </summary>
        /// <param name="message">消息</param>
        protected void LogWarning(string message)
        {
            Output.WriteLine($"[WARN] {DateTime.Now:HH:mm:ss.fff} {message}");
        }

        /// <summary>
        /// 记录错误
        /// </summary>
        /// <param name="message">消息</param>
        protected void LogError(string message)
        {
            Output.WriteLine($"[ERROR] {DateTime.Now:HH:mm:ss.fff} {message}");
        }

        /// <summary>
        /// 等待指定时间
        /// </summary>
        /// <param name="milliseconds">毫秒数</param>
        protected static async Task WaitAsync(int milliseconds)
        {
            await Task.Delay(milliseconds);
        }

        /// <summary>
        /// 等待条件满足
        /// </summary>
        /// <param name="condition">条件函数</param>
        /// <param name="timeoutMs">超时时间（毫秒）</param>
        /// <param name="intervalMs">检查间隔（毫秒）</param>
        /// <returns>是否在超时前满足条件</returns>
        protected static async Task<bool> WaitForConditionAsync(Func<bool> condition, int timeoutMs = 5000, int intervalMs = 100)
        {
            var timeout = DateTime.UtcNow.AddMilliseconds(timeoutMs);
            
            while (DateTime.UtcNow < timeout)
            {
                if (condition())
                    return true;
                    
                await Task.Delay(intervalMs);
            }
            
            return false;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed && disposing)
            {
                Cleanup();
                _disposed = true;
            }
        }
    }
}